#pragma once

#include <string>
#include <memory>
#include <omp.h>

#include "../utils/graph.hh"
#include "../utils/painter.hh"
#include "../utils/heap.hh"
#include "../utils/concurrent-queue.hh"
#include "utils.hh"

namespace icesp
{
    namespace kernal
    {
        struct no_atomic
        {
            using twod_cqueue_type = twod_concurrent_queue<>;

            static double compute(graph::adj_matrix& mat, painter& c, int source, int target);

            static void init(int nthreads, int nrelax)
            {
                no_atomic::nthreads = nthreads;
                no_atomic::nrelax = nrelax;
            }

            static constexpr bool is_pad{false};
            static std::string const name;
        private:
            static bool update_queue_empty(int pid);
            static bool heap_queue_empty  (int pid);

            static void worker(graph::adj_matrix& mat);
            static void relax (int pid, graph::adj_matrix& mat);
            static void adjust(int pid, graph::adj_matrix& mat);

            static int nthreads;
            static int nrelax;

            // TODO std::shared_ptr<>
            static int const* colors;
            static heaps* _heaps;
            static twod_cqueue_type* queues;

            static volatile int* versions;
        };
    }
}

